import random
import numpy as  np


# 按照指定方式进行编码,len表示DNA长度
def Code(method, length) -> list[int]:
    result = []
    if method == 1:
        for i in range(0, length):
            result.append(i)
        np.random.shuffle(result)
    else:
        for i in range(0, length):
            result.append(random.randint(0, 1))
    return result


# 输入编码和编码方式,delt表示距离矩阵
def solveCode(code, method, delt=0):
    length = len(code)
    b = 1
    result = 0
    if method == 1:
        new_code = [0] * length
        for i in range(0, length):
            new_code[code[i]] = i
        for i in range(0, length - 1):
            result += delt[code[i]][code[i + 1]]
    else:
        new_code = code
        new_code.reverse()
        for i in range(0, length):
            result = result + b * new_code[i]
            b = b * 2
    return result


# 本例采用二进制编码，求解二次函数最值
INDIVIDUAL = 500
GWNWEATION = 10000
VARIATION = 0.1
LENGTH = 3
COPY = 0.3
SWAP = 0.8
METHOD = 2

species = [[]] * INDIVIDUAL
adapt = [0] * INDIVIDUAL
# 初始种群
for i in range(0, INDIVIDUAL):
    species[i] = Code(METHOD, LENGTH)
    adapt[i] = solveCode(species[i], METHOD)
copy_num = int(INDIVIDUAL * COPY)
for gen in range(0, GWNWEATION):
    # 选择排序对适应度从小到大进行排序
    for i in range(0, LENGTH - 1):
        for j in range(i, LENGTH):
            if adapt[i] > adapt[j]:
                temp = adapt[i]
                adapt[i] = adapt[j]
                adapt[j] = temp
                temp = species[i]
                species[i] = species[j]
                species[j] = temp
    # 死亡加复制
    for i in range(0, copy_num):
        adapt[i] = adapt[-1 - i]
        species[i] = species[-1 - i]
    # 交换
    key = [-1, -1]
    num = 0
    for i in range(0, INDIVIDUAL):
        is_ = random.random()
        if is_ < SWAP:
            key[num] = i
            num += 1
        if num == 2:
            num = 0
            pos = random.randint(0, LENGTH - 1)
            temp = species[key[0]][pos:]
            species[key[0]][pos:] = species[key[1]][pos:]
            species[key[1]][pos:] = temp
            adapt[key[0]] = solveCode(species[key[0]], METHOD, 0)
            adapt[key[1]] = solveCode(species[key[1]], METHOD, 0)
            key = [-1, -1]
    # 变异
    for i in range(0, INDIVIDUAL):
        is_ = random.random()
        if is_ < VARIATION:
            pos = random.randint(0, LENGTH - 1)
            species[i][pos] = ~species[i][pos]
            adapt[i] = solveCode(species[i], METHOD, 0)
print(max(adapt))
